import { WebSocketServer } from 'ws'
import global from './global'
import initWindow from './initWindow'
import Win32Utils from './win32Utils'
import log from 'electron-log'

export default class websocket {
  static port: number = 50301
  static pingTimeout: NodeJS.Timeout | null = null

  static createWebsocket = () => {
    const wss = new WebSocketServer({ port: this.port })
    wss.on('listening', () => {
      console.log('WebSocket 服务器已启动')
    })
    wss.on('connection', async (ws: any) => {
      console.log('websocket连接成功')

      const schedulePing = () => {
        ws.ping()
        this.pingTimeout = setTimeout(schedulePing, 5000)
      }

      schedulePing()

      // 监听来自客户端的消息
      ws.on('message', async (message: any) => {
        // 先将消息转换为字符串
        const messageStr = message.toString()
        console.log(`收到原始消息:`, messageStr)
        if (messageStr === 'ping' || messageStr === 'pong') {
          console.log(`收到客户端的心跳: ${messageStr}`)
          return
        }
        let json_message: any
        try {
          json_message = JSON.parse(message) // 尝试解析 JSON
          console.log(`收到websocket发送过来的消息, 消息类型为${json_message.type}`)
          console.log(`完整消息内容:`, JSON.stringify(json_message, null, 2))
        } catch (e) {
          console.error('解析 JSON 时出错:', e)
        }

        switch (json_message.type) {
          case 'userinfo': // 当前登陆人信息
            console.log(`收到userinfo消息, 消息内容为`, json_message.msg)
            let list = json_message.msg
            if (!global.idToShopInfo.has(list.cs_id)) {
              global.idToShopInfo.set(list.cs_id, {
                username: list.username,
                ws: ws,
                mall_name: list.mall_name,
                visibilityState: list.visibilityState,
                isNeedAnswer: false,
                platform: list.platform
              })
              global.mainWindow?.webContents.send('login-shop', {
                mall_name: list.mall_name,
                username: list.username
              })
            }
            if (!global.shopNameToIsGetGoods.has(list.mall_name)) {
              global.shopNameToIsGetGoods.set(list.mall_name, false)
            }
            if (list.platform == 'pdd' && !global.isPddWindowOpen) {
              initWindow.createFollowWindow(list.platform)
              // ws.send(JSON.stringify({ type: 'getHotGoodsList' }))
              global.isPddWindowOpen = true
            }
            global.followWindow?.webContents.send('customer-service', {
              name: `${list.mall_name}:${list.username}`,
              isNeedAnswer: list.isNeedAnswer
            })
            ws.send(JSON.stringify({ type: 'getCustomerName' }))
            break
          case 'switch_customer': // 切换客户
            let userInfo = {
              uid: json_message.msg.UIDSwitchInfo,
              nickname: json_message.msg.userinfo.nickname ? json_message.msg.userinfo.nickname : ''
            }
            if (userInfo.uid != '' && userInfo.nickname != '') {
              global.customerIdToCustomerNameAndMsgs.set(userInfo.uid, {
                customerName: userInfo.nickname,
                msgs: []
              })
            }
            global.followWindow?.webContents.send('customer-name', userInfo.nickname)
            ws.send(JSON.stringify({ type: 'getMsgs', msg: userInfo.uid }))
            console.log(`收到switch_customer消息, 消息内容为`, userInfo)
            break
          case 'visibility_change':
            for (const [_, value] of global.idToShopInfo) {
              value.visibilityState = 'hidden'
              if (value.ws == ws) {
                value.visibilityState = 'visible'
                let list = {
                  name: `${value.mall_name}:${value.username}`,
                  isNeedAnswer: value.isNeedAnswer
                }
                global.followWindow?.webContents.send('customer-service', list)
              }
            }
            break
          case 'msgs':
            let msg = json_message.msg[0]
            let userId = msg.from.role == 'user' ? msg.from.uid : msg.to.uid
            if (global.customerIdToCustomerNameAndMsgs.has(userId)) {
              ;(global.customerIdToCustomerNameAndMsgs.get(userId) as customerNameAndMsgs).msgs =
                json_message.msg
            }
            console.log('收到msgs消息:', global.customerIdToCustomerNameAndMsgs)

            break
          case 'goodsList':
            console.log('收到goodsList消息:', JSON.stringify(json_message.msg))
            break
          case 'isNeedAnswer':
            for (const [_, value] of global.idToShopInfo) {
              if (value.ws == ws) {
                value.isNeedAnswer = true
                let list = {
                  name: `${value.mall_name}:${value.username}`,
                  isNeedAnswer: value.isNeedAnswer
                }
                global.followWindow?.webContents.send('customer-service', list)
              }
            }
            break
          case 'autoAnswer':
            global.mainWindow?.webContents.send('change-loading-text', '答题完成')
            setTimeout(() => {
              global.followWindow?.webContents.send('change-loading', false)
            }, 1000 * 3)
            break
        }
      })

      ws.on('close', () => {
        console.log(`收到WebSocket的close`)
        this.returnWs(ws)
      })

      ws.on('error', (e: any) => {
        console.log(`收到WebSocket的error，内容为`, e)
        this.returnWs(ws)
      })
    })

    return wss
  }

  static returnWs = (ws: websocket) => {
    //找到idToShopInfo中对应的ws
    for (const [key, value] of global.idToShopInfo) {
      if (value.ws === ws) {
        global.mainWindow?.webContents.send('loginOut-shop', {
          mall_name: value.mall_name,
          username: value.username
        })
        global.idToShopInfo.delete(key)
      }
    }
    if (global.idToShopInfo.size === 0) {
      global.isPddWindowOpen = false
      global.followWindow?.close()
      clearInterval(Win32Utils.followTimerStop)
      Win32Utils.followTimerStop = null
    }
    if (this.pingTimeout) {
      clearTimeout(this.pingTimeout)
      this.pingTimeout = null
    }
  }
}
